#import "BWThreadColor.h"

@implementation BWThreadColor

- (void) dealloc
{
    [manufacturerName release];
    [manufacturerID release];

    [color release];
    [name release];

    [cachedSwatch release];

    [super dealloc];

} // dealloc


- (NSString *) manufacturerName
{
    return (manufacturerName);
} // manufacturerName


- (void) setManufacturerName: (NSString *) n
{
    [manufacturerName release];
    manufacturerName = [n copy];

} // setManufacturerName



- (NSString *) manufacturerID
{
    return (manufacturerID);
} // manufacturerID


- (void) setManufacturerID: (NSString *) mid
{
    [manufacturerID release];
    manufacturerID = [mid copy];

} // setManufacturerID


- (NSString *) name
{
    return (name);
} // name


- (void) setName: (NSString *) theName
{
    [name release];
    name = [theName copy];

} // setName


- (NSColor *) color
{
    return (color);
} // color


- (void) setColor: (NSColor *) theColor
{
    [theColor retain];
    [color release];
    color = [theColor retain];

} // setColor


- (void) encodeWithCoder: (NSCoder *) coder
{
    [coder encodeObject: manufacturerName];
    [coder encodeObject: manufacturerID];
    [coder encodeObject: color];
    [coder encodeObject: name];
    
} // encodeWithCoder


- (id) initWithCoder: (NSCoder *) decoder
{
    if (self = [super init]) {
        manufacturerName = [decoder decodeObject];
        [manufacturerName retain];

        manufacturerID = [decoder decodeObject];
        [manufacturerID retain];

        color = [decoder decodeObject];
        [color retain];

        name = [decoder decodeObject];
        [name retain];
    }

    return (self);

} // initWithCoder


- (NSComparisonResult) compareFloat: (float) thing1  withFloat: (float) thing2
{
    NSComparisonResult result;

    float diff;
    diff = thing1 - thing2;

    if (fabs(diff) < 0.0001) {
        result = NSOrderedSame;
    } else if (diff < 0) { 
        result = NSOrderedAscending;
    } else {
        result = NSOrderedDescending;
    }

    return (result);

} // compareFloat


- (NSComparisonResult) compareManufacturerID: (BWThreadColor *) thing2
{
    NSComparisonResult result;

    // sort numbers numerically, and then sort names before them
    // alphabetically
    BOOL thing1Numbers = YES;
    BOOL thing2Numbers = YES;

    NSCharacterSet *nonDigits;
    nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    
    NSRange range;
    range = [manufacturerID rangeOfCharacterFromSet: nonDigits];
    if (range.length != 0) {
        thing1Numbers = NO;
    }

    range = [[thing2 manufacturerID] rangeOfCharacterFromSet: nonDigits];
    if (range.length != 0) {
        thing2Numbers = NO;
    }

    if (thing1Numbers && !thing2Numbers) {
        result = NSOrderedDescending;

    } else if (thing2Numbers && !thing1Numbers) {
        result = NSOrderedAscending;

    } else if (thing1Numbers && thing2Numbers) {
        float val1;
        float val2;
        val1 = [manufacturerID floatValue];
        val2 = [[thing2 manufacturerID] floatValue];

        result = [self compareFloat: val1
                       withFloat: val2];
    } else {
        result = [manufacturerID caseInsensitiveCompare: [thing2 manufacturerID]];
    }

    return (result);

} // compareManufacturerID


// for some odd reason, this doesn't sort it reliably
- (NSComparisonResult) compareColor: (BWThreadColor *) thing2
{
    NSComparisonResult result = NSOrderedSame;;

    NSColor *color2;
    color2 = [thing2 color];

    float val1, val2;

#define RGB 0
#define HSV 1
#define HS_V 0 // hue + saturation, then value
#define MASKED_RGB 0
#define CMYK 0

#if CMYK
    NSColor *cmyk1 = [color colorUsingColorSpaceName: NSDeviceCMYKColorSpace];
    NSColor *cmyk2 = [color2 colorUsingColorSpaceName: NSDeviceCMYKColorSpace];

    float c1, m1, y1, k1;
    float c2, m2, y2, k2;
    float dummy;

    [cmyk1 getCyan: &c1  magenta: &m1  yellow: &y1  black: &k2  alpha: &dummy];
    [cmyk2 getCyan: &c2  magenta: &m2  yellow: &y2  black: &k2  alpha: &dummy];

    if (result == NSOrderedSame) {
        val1 = c1;
        val2 = c2;
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    if (result == NSOrderedSame) {
        val1 = m1;
        val2 = m2;
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    if (result == NSOrderedSame) {
        val1 = y1;
        val2 = y2;
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    if (result == NSOrderedSame) {
        val1 = k1;
        val2 = k2;
        result = [self compareFloat: val1
                       withFloat: val2];
    }
#endif // CMYK

#if MASKED_RGB
    float r1, g1, b1;
    float r2, g2, b2;

    r1 = [color redComponent];
    g1 = [color greenComponent];
    b1 = [color blueComponent];

    r2 = [color2 redComponent];
    g2 = [color2 greenComponent];
    b2 = [color2 blueComponent];

    if (result == NSOrderedSame) {
        val1 = r1 * 10 + g1;
        val2 = r2 * 10 + g2;
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    if (result == NSOrderedSame) {
        val1 = b1;
        val2 = b2;
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    if (result == NSOrderedSame) {

    }

#endif

#if RGB
    if (result == NSOrderedSame) {
        val1 = [color redComponent];
        val2 = [color2 redComponent];
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    
    if (result == NSOrderedSame) {
        val1 = [color greenComponent];
        val2 = [color2 greenComponent];
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    
    if (result == NSOrderedSame) {
        val1 = [color blueComponent];
        val2 = [color2 blueComponent];
        result = [self compareFloat: val1
                       withFloat: val2];
    }
    
#endif

#if HSV
    if (result == NSOrderedSame) {
        val1 = [color hueComponent];
        val2 = [[thing2 color] hueComponent];
        
        result = [self compareFloat: val1
                       withFloat: val2];
    }

    if (result == NSOrderedSame) {
        val1 = [color saturationComponent];
        val2 = [[thing2 color] saturationComponent];
        result = [self compareFloat: val1
                       withFloat: val2];
    }

    if (result == NSOrderedSame) {
        val1 = [color brightnessComponent];
        val2 = [[thing2 color] brightnessComponent];
        result = [self compareFloat: val1
                       withFloat: val2];
    }

#endif // HSV

#if HS_V
    if (result == NSOrderedSame) {
        val1 = [color hueComponent] + [color saturationComponent] * 0.5;
        val2 = [[thing2 color] hueComponent] 
            + [[thing2 color] saturationComponent] * 0.5;
        
        result = [self compareFloat: val1
                       withFloat: val2];
    }

    if (result == NSOrderedSame) {
        val1 = [color brightnessComponent];
        val2 = [[thing2 color] brightnessComponent];
        result = [self compareFloat: val1
                       withFloat: val2];
    }

#endif // HS_V

    return (result);

} // compareColor


- (NSComparisonResult) compareName: (BWThreadColor *) thing2
{
    NSComparisonResult result;
    
    result = [name caseInsensitiveCompare: [thing2 name]];

    return (result);

} // compareName


- (BOOL) isEqualTo: (id) object
{
    BWThreadColor *thing2;
    thing2 = object;

    BOOL result = NO;

    if (([self compareName: thing2] == NSOrderedSame)
        && ([self compareColor: thing2] == NSOrderedSame)
        && ([self compareName: thing2] == NSOrderedSame)) {
        result = YES;
    }

    return (result);

} // isEqualTo


- (NSImage *) colorSwatch
{
    if (cachedSwatch == nil) {
        NSRect rect;
        rect.origin = NSZeroPoint;
        rect.size = NSMakeSize (30, 30);
        
        cachedSwatch = [[NSImage alloc] initWithSize: rect.size];
        
        [cachedSwatch lockFocus];
        [[self color] set];
        
        [NSBezierPath fillRect: rect];
        [cachedSwatch unlockFocus];
    }
    
    return (cachedSwatch);
        
} // colorSwatch


// hackage to get the tableview columns to auto-sort correctly
// Somehow need to get a 'self' value so that one of our "compareXYZ:"
// methods can be used.  The problem is if the same "sort key" is used,
// all three table headers appear in their sorted state, and the actual
// sorting is megaweird.

- (BWThreadColor *) self1
{
    return (self);
} // nork


- (BWThreadColor *) self2
{
    return (self);
} // nork

- (BWThreadColor *) self3
{
    return (self);
} // nork

- (NSString *) hsv
{
    float h, s, v;
    h = [color hueComponent];
    s = [color saturationComponent];
    v = [color brightnessComponent];

    NSString *string;
    string = [NSString stringWithFormat: @"%0.3f %0.3f %0.3f",
                       h, s, v];

    return (string);
} // hsv

- (NSString *) rgb
{
    float r, g, b;

    r = [color redComponent];
    g = [color greenComponent];
    b = [color blueComponent];

    NSString *string;
    string = [NSString stringWithFormat: @"%0.3f %0.3f %0.3f",
                       r, g, b];

    return (string);
} // hsv


- (id) copyWithZone: (NSZone *) zone
{
    BWThreadColor *copy = [[[self class] alloc] init];

    [copy setManufacturerName: manufacturerName];
    [copy setManufacturerID: manufacturerID];
    [copy setName: name];
    [copy setColor: color];

    return (copy);

} // copyWithZone



@end // BWColor


